
/**
 * A Privacy IQ Packet, is used by the {@link org.jivesoftware.smack.PrivacyListManager}
 * and {@link org.jivesoftware.smack.provider.PrivacyProvider} to allow and block
 * communications from other users. It contains the appropriate structure to suit
 * user-defined privacy lists. Different configured Privacy packages are used in the
 * Server ?Manager communication in order to:
 * <ul>
 * <li>Retrieving one's privacy lists. 
 * <li>Adding, removing, and editing one's privacy lists. 
 * <li>Setting, changing, or declining active lists. 
 * <li>Setting, changing, or declining the default list (i.e., the list that is active by default). 
 * </ul>
 * Privacy Items can handle different kind of blocking communications based on JID, group, 
 * subscription type or globally {@link PrivacyItem}
 * 
 * @author Francisco Vives
 */
class Privacy : public IQ {
public
    /**
     * Set or update a privacy list with privacy items.
     *
     * @param listName the name of the new privacy list.
     * @param listItem the {@link PrivacyItem} that rules the list.
     * @return the privacy List.
     */
    std::list<PrivacyItem*> setPrivacyList(std::string & listName, std::list<PrivacyItem*> & listItem);

    /**
     * Set the active list based on the default list.
     *
     * @return the active List.
     */
	std::list<PrivacyItem*> setActivePrivacyList();
	
    /**
     * Deletes an existing privacy list. If the privacy list being deleted was the default list 
     * then the user will end up with no default list. Therefore, the user will have to set a new 
     * default list.
     *
     * @param listName the name of the list being deleted.
     */
    void deletePrivacyList(std::string & listName);
	
    /**
     * Returns the active privacy list or <tt>null</tt> if none was found.
     *
     * @return list with {@link PrivacyItem} or <tt>null</tt> if none was found.
     */
	std::vector<PrivacyItem*> getActivePrivacyList();
	
    /**
     * Returns the default privacy list or <tt>null</tt> if none was found.
     *
     * @return list with {@link PrivacyItem} or <tt>null</tt> if none was found.
     */
	std::vector<PrivacyItem*> getDefaultPrivacyList();
	
    /**
     * Returns a specific privacy list.
     *
     * @param listName the name of the list to get.
     * @return a List with {@link PrivacyItem}
     */
	std::vector<PrivacyItem*> getPrivacyList(std::string & listName);
	
    /**
     * Returns the privacy item in the specified order.
     *
     * @param listName the name of the privacy list.
     * @param order the order of the element.
     * @return a List with {@link PrivacyItem}
     */
    PrivacyItem * getItem(std::string & listName, int order);
	
    /**
     * Sets a given privacy list as the new user default list.
     *
     * @param newDefault the new default privacy list.
     * @return if the default list was changed.
     */
    bool changeDefaultList(std::string & newDefault);
	
    /**
     * Remove the list.
     *
     * @param listName name of the list to remove.
     */
    void deleteList(std::string & listName);
	 
    /**
     * Returns the name associated with the active list set for the session. Communications
     * will be verified against the active list.
     *
     * @return the name of the active list.
     */
	std::string getActiveName() ;

    /**
     * Sets the name associated with the active list set for the session. Communications
     * will be verified against the active list.
     * 
     * @param activeName is the name of the active list.
     */
	void setActiveName(std::string & activeName) ;
	
    /**
     * Returns the name of the default list that applies to the user as a whole. Default list is 
     * processed if there is no active list set for the target session/resource to which a stanza 
     * is addressed, or if there are no current sessions for the user.
     * 
     * @return the name of the default list.
     */
	std::string getDefaultName() ;

    /**
     * Sets the name of the default list that applies to the user as a whole. Default list is 
     * processed if there is no active list set for the target session/resource to which a stanza 
     * is addressed, or if there are no current sessions for the user.
     * 
     * If there is no default list set, then all Privacy Items are processed.
     * 
     * @param defaultName is the name of the default list.
     */
	void setDefaultName(std::string & defaultName) ;

    /**
     * Returns the collection of privacy list that the user holds. A Privacy List contains a set of 
     * rules that define if communication with the list owner is allowed or denied. 
     * Users may have zero, one or more privacy items.
     * 
     * @return a map where the key is the name of the list and the value the 
     * collection of privacy items.
     */
	std::map<std::string, std::vector<PrivacyItem*>> getItemLists() ;

    /** 
     * Returns whether the receiver allows or declines the use of an active list.
     * 
     * @return the decline status of the list.
     */
	bool isDeclineActiveList() ;

    /** 
     * Sets whether the receiver allows or declines the use of an active list.
     * 
     * @param declineActiveList indicates if the receiver declines the use of an active list.
     */
	void setDeclineActiveList(bool declineActiveList) {
		this->declineActiveList = declineActiveList;
	}

    /** 
     * Returns whether the receiver allows or declines the use of a default list.
     * 
     * @return the decline status of the list.
     */
	bool isDeclineDefaultList() {
		return declineDefaultList;
	}
	
    /** 
     * Sets whether the receiver allows or declines the use of a default list.
     * 
     * @param declineDefaultList indicates if the receiver declines the use of a default list.
     */
	void setDeclineDefaultList(bool declineDefaultList) ;

	/** 
     * Returns all the list names the user has defined to group restrictions.
     * 
     * @return a Set with Strings containing every list names.
     */
	std::list<std::string> getPrivacyListNames() ;

	std::string getChildElementXML();

private:	
		
	/** declineActiveList is true when the user declines the use of the active list **/
	bool declineActiveList;
	/** activeName is the name associated with the active list set for the session **/
	std::string activeName;
	/** declineDefaultList is true when the user declines the use of the default list **/
	bool declineDefaultList;
	/** defaultName is the name of the default list that applies to the user as a whole **/
	std::string defaultName;
	/** itemLists holds the set of privacy items classified in lists. It is a map where the 
	 * key is the name of the list and the value a collection with privacy items. **/
	std::map<std::string, std::list<PrivacyItem*>> itemLists;
};
